Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mmu unify task 1 - sv32 and sv39 #1707

Closed
wants to merge 67 commits into from

Conversation

AngelaGonzalezMarino
Copy link
Contributor

Merge of sv32 and sv39 MMUs.
Parametrization strategy followed for new parameters.

correct also ASID_LEN parameter propagation
Correct value assignment req_port_o.data_be and req_port_o.data_be for the sv39 case.
Comment on lines 32 to 225
logic shared_tlb_hit;

logic itlb_req;

// Assignments
assign itlb_lu_access = icache_areq_i.fetch_req;
assign dtlb_lu_access = lsu_req_i;

logic [riscv::VLEN-1:0] lu_vaddr_i [HYP_EXT:0];
assign lu_vaddr_i[0]=icache_areq_i.fetch_vaddr;

cva6_tlb #(
.CVA6Cfg (CVA6Cfg),
.TLB_ENTRIES(INSTR_TLB_ENTRIES),
.ASID_WIDTH (ASID_WIDTH),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_itlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),

.update_i(update_itlb),

.lu_access_i (itlb_lu_access),
.lu_asid_i (asid_i),
.asid_to_be_flushed_i (asid_to_be_flushed_i),
.vaddr_to_be_flushed_i(vaddr_to_be_flushed_i),
.lu_vaddr_i (lu_vaddr_i),
.lu_content_o (itlb_content),

.lu_is_page_o(itlb_is_page),
.lu_hit_o (itlb_lu_hit),
.v_st_enbl_i(1)
);

cva6_tlb #(
.CVA6Cfg (CVA6Cfg),
.TLB_ENTRIES(DATA_TLB_ENTRIES),
.ASID_WIDTH (ASID_WIDTH),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_dtlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),

.update_i(update_dtlb),

.lu_access_i (dtlb_lu_access),
.lu_asid_i (asid_i),
.asid_to_be_flushed_i (asid_to_be_flushed_i),
.vaddr_to_be_flushed_i(vaddr_to_be_flushed_i),
.lu_vaddr_i (lsu_vaddr_i),
.lu_content_o (dtlb_content),

.lu_is_page_o(dtlb_is_page),
.lu_hit_o (dtlb_lu_hit),
.v_st_enbl_i(1)
);

cva6_shared_tlb #(
.CVA6Cfg (CVA6Cfg),
.SHARED_TLB_DEPTH(64),
.SHARED_TLB_WAYS (2),
.ASID_WIDTH (ASID_WIDTH[0]),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_shared_tlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),

.enable_translation_i (enable_translation_i),
.en_ld_st_translation_i(en_ld_st_translation_i),

.asid_i (asid_i[0]),
// from TLBs
// did we miss?
.itlb_access_i(itlb_lu_access),
.itlb_hit_i (itlb_lu_hit),
.itlb_vaddr_i (icache_areq_i.fetch_vaddr),

.dtlb_access_i(dtlb_lu_access),
.dtlb_hit_i (dtlb_lu_hit),
.dtlb_vaddr_i (lsu_vaddr_i[0]),

// to TLBs, update logic
.itlb_update_o(update_itlb),
.dtlb_update_o(update_dtlb),

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
input logic clk_i,
input logic rst_ni,
input logic flush_i,
input logic enable_translation_i,
input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores
// IF interface
input icache_arsp_t icache_areq_i,
output icache_areq_t icache_areq_o,
// LSU interface
// this is a more minimalistic interface because the actual addressing logic is handled
// in the LSU as we distinguish load and stores, what we do here is simple address translation
input exception_t misaligned_ex_i,
input logic lsu_req_i, // request address translation
input logic [riscv::VLEN-1:0] lsu_vaddr_i[HYP_EXT:0], // virtual address in
input logic lsu_is_store_i, // the translation is requested by a store
// if we need to walk the page table we can't grant in the same cycle
// Cycle 0
output logic lsu_dtlb_hit_o, // sent in the same cycle as the request if translation hits in the DTLB
output logic [riscv::PPNW-1:0] lsu_dtlb_ppn_o, // ppn (send same cycle as hit)
// Cycle 1
output logic lsu_valid_o, // translation is valid
output logic [riscv::PLEN-1:0] lsu_paddr_o, // translated address
output exception_t lsu_exception_o, // address translation threw an exception
// General control signals
input riscv::priv_lvl_t priv_lvl_i,
input riscv::priv_lvl_t ld_st_priv_lvl_i,
input logic sum_i,
input logic mxr_i,
// input logic flag_mprv_i,
input logic [riscv::PPNW-1:0] satp_ppn_i,
input logic [ASID_WIDTH[0]-1:0] asid_i [HYP_EXT:0],
input logic [ASID_WIDTH[0]-1:0] asid_to_be_flushed_i [HYP_EXT:0],
input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i [HYP_EXT:0],
input logic flush_tlb_i,
// Performance counters
output logic itlb_miss_o,
output logic dtlb_miss_o,
// PTW memory interface
input dcache_req_o_t req_port_i,
output dcache_req_i_t req_port_o,
// PMP
input riscv::pmpcfg_t [15:0] pmpcfg_i,
input logic [15:0][riscv::PLEN-3:0] pmpaddr_i
);
// memory management, pte for cva6
localparam type pte_cva6_t = struct packed {
// typedef struct packed {
logic [riscv::PPNW-1:0] ppn; // PPN length for
logic [1:0] rsw;
logic d;
logic a;
logic g;
logic u;
logic x;
logic w;
logic r;
logic v;
} ;
localparam type tlb_update_cva6_t = struct packed {
// typedef struct packed {
logic valid; // valid flag
logic [HYP_EXT:0][PT_LEVELS-2:0] is_page; //
logic [VPN_LEN-1:0] vpn; //
logic [HYP_EXT:0][ASID_LEN-1:0] asid; //
pte_cva6_t [HYP_EXT:0] content;
} ;
logic iaccess_err; // insufficient privilege to access this instruction page
logic daccess_err; // insufficient privilege to access this data page
logic ptw_active; // PTW is currently walking a page table
logic walking_instr; // PTW is walking because of an ITLB miss
logic ptw_error; // PTW threw an exception
logic ptw_access_exception; // PTW threw an access exception (PMPs)
logic [riscv::PLEN-1:0] ptw_bad_paddr; // PTW PMP exception bad physical addr
logic [riscv::VLEN-1:0] update_vaddr;
// tlb_update_t update_ptw_itlb, update_ptw_dtlb;
tlb_update_cva6_t update_itlb, update_dtlb, update_shared_tlb;
logic itlb_lu_access;
pte_cva6_t [HYP_EXT:0] itlb_content ;
logic [PT_LEVELS-2:0] itlb_is_page;
logic itlb_lu_hit;
logic dtlb_lu_access;
pte_cva6_t [HYP_EXT:0] dtlb_content;
logic [PT_LEVELS-2:0] dtlb_is_page;
logic dtlb_lu_hit;
logic shared_tlb_access;
logic [riscv::VLEN-1:0] shared_tlb_vaddr;
logic shared_tlb_hit;
logic itlb_req;
// Assignments
assign itlb_lu_access = icache_areq_i.fetch_req;
assign dtlb_lu_access = lsu_req_i;
logic [riscv::VLEN-1:0] lu_vaddr_i [HYP_EXT:0];
assign lu_vaddr_i[0]=icache_areq_i.fetch_vaddr;
cva6_tlb #(
.CVA6Cfg (CVA6Cfg),
.TLB_ENTRIES(INSTR_TLB_ENTRIES),
.ASID_WIDTH (ASID_WIDTH),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_itlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),
.update_i(update_itlb),
.lu_access_i (itlb_lu_access),
.lu_asid_i (asid_i),
.asid_to_be_flushed_i (asid_to_be_flushed_i),
.vaddr_to_be_flushed_i(vaddr_to_be_flushed_i),
.lu_vaddr_i (lu_vaddr_i),
.lu_content_o (itlb_content),
.lu_is_page_o(itlb_is_page),
.lu_hit_o (itlb_lu_hit),
.v_st_enbl_i(1)
);
cva6_tlb #(
.CVA6Cfg (CVA6Cfg),
.TLB_ENTRIES(DATA_TLB_ENTRIES),
.ASID_WIDTH (ASID_WIDTH),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_dtlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),
.update_i(update_dtlb),
.lu_access_i (dtlb_lu_access),
.lu_asid_i (asid_i),
.asid_to_be_flushed_i (asid_to_be_flushed_i),
.vaddr_to_be_flushed_i(vaddr_to_be_flushed_i),
.lu_vaddr_i (lsu_vaddr_i),
.lu_content_o (dtlb_content),
.lu_is_page_o(dtlb_is_page),
.lu_hit_o (dtlb_lu_hit),
.v_st_enbl_i(1)
);
cva6_shared_tlb #(
.CVA6Cfg (CVA6Cfg),
.SHARED_TLB_DEPTH(64),
.SHARED_TLB_WAYS (2),
.ASID_WIDTH (ASID_WIDTH[0]),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_shared_tlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),
.enable_translation_i (enable_translation_i),
.en_ld_st_translation_i(en_ld_st_translation_i),
.asid_i (asid_i[0]),
// from TLBs
// did we miss?
.itlb_access_i(itlb_lu_access),
.itlb_hit_i (itlb_lu_hit),
.itlb_vaddr_i (icache_areq_i.fetch_vaddr),
.dtlb_access_i(dtlb_lu_access),
.dtlb_hit_i (dtlb_lu_hit),
.dtlb_vaddr_i (lsu_vaddr_i[0]),
// to TLBs, update logic
.itlb_update_o(update_itlb),
.dtlb_update_o(update_dtlb),
input logic clk_i,
input logic rst_ni,
input logic flush_i,
input logic enable_translation_i,
input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores
// IF interface
input icache_arsp_t icache_areq_i,
output icache_areq_t icache_areq_o,
// LSU interface
// this is a more minimalistic interface because the actual addressing logic is handled
// in the LSU as we distinguish load and stores, what we do here is simple address translation
input exception_t misaligned_ex_i,
input logic lsu_req_i, // request address translation
input logic [riscv::VLEN-1:0] lsu_vaddr_i[HYP_EXT:0], // virtual address in
input logic lsu_is_store_i, // the translation is requested by a store
// if we need to walk the page table we can't grant in the same cycle
// Cycle 0
output logic lsu_dtlb_hit_o, // sent in the same cycle as the request if translation hits in the DTLB
output logic [riscv::PPNW-1:0] lsu_dtlb_ppn_o, // ppn (send same cycle as hit)
// Cycle 1
output logic lsu_valid_o, // translation is valid
output logic [riscv::PLEN-1:0] lsu_paddr_o, // translated address
output exception_t lsu_exception_o, // address translation threw an exception
// General control signals
input riscv::priv_lvl_t priv_lvl_i,
input riscv::priv_lvl_t ld_st_priv_lvl_i,
input logic sum_i,
input logic mxr_i,
// input logic flag_mprv_i,
input logic [riscv::PPNW-1:0] satp_ppn_i,
input logic [ASID_WIDTH[0]-1:0] asid_i[HYP_EXT:0],
input logic [ASID_WIDTH[0]-1:0] asid_to_be_flushed_i[HYP_EXT:0],
input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i[HYP_EXT:0],
input logic flush_tlb_i,


);


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
// memory management, pte for cva6
localparam type pte_cva6_t = struct packed {
// typedef struct packed {
logic [riscv::PPNW-1:0] ppn; // PPN length for
logic [1:0] rsw;
logic d;
logic a;
logic g;
logic u;
logic x;
logic w;
logic r;
logic v;
};
localparam type tlb_update_cva6_t = struct packed {
// typedef struct packed {
logic valid; // valid flag
logic [HYP_EXT:0][PT_LEVELS-2:0] is_page; //
logic [VPN_LEN-1:0] vpn; //
logic [HYP_EXT:0][ASID_LEN-1:0] asid; //
pte_cva6_t [HYP_EXT:0] content;
};
logic iaccess_err; // insufficient privilege to access this instruction page
logic daccess_err; // insufficient privilege to access this data page
logic ptw_active; // PTW is currently walking a page table
logic walking_instr; // PTW is walking because of an ITLB miss
logic ptw_error; // PTW threw an exception
logic ptw_access_exception; // PTW threw an access exception (PMPs)
logic [riscv::PLEN-1:0] ptw_bad_paddr; // PTW PMP exception bad physical addr
logic [riscv::VLEN-1:0] update_vaddr;
// tlb_update_t update_ptw_itlb, update_ptw_dtlb;
tlb_update_cva6_t update_itlb, update_dtlb, update_shared_tlb;
logic itlb_lu_access;
pte_cva6_t [ HYP_EXT:0] itlb_content;
logic [ PT_LEVELS-2:0] itlb_is_page;
logic itlb_lu_hit;
logic dtlb_lu_access;
pte_cva6_t [ HYP_EXT:0] dtlb_content;
logic [ PT_LEVELS-2:0] dtlb_is_page;
logic dtlb_lu_hit;
logic shared_tlb_access;
logic [riscv::VLEN-1:0] shared_tlb_vaddr;
logic shared_tlb_hit;
logic itlb_req;
// Assignments
assign itlb_lu_access = icache_areq_i.fetch_req;
assign dtlb_lu_access = lsu_req_i;
logic [riscv::VLEN-1:0] lu_vaddr_i[HYP_EXT:0];
assign lu_vaddr_i[0] = icache_areq_i.fetch_vaddr;
cva6_tlb #(
.CVA6Cfg (CVA6Cfg),
.TLB_ENTRIES (INSTR_TLB_ENTRIES),
.ASID_WIDTH (ASID_WIDTH),
.ASID_LEN (ASID_LEN),
.VPN_LEN (VPN_LEN),
.PT_LEVELS (PT_LEVELS),
.pte_cva6_t (pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_itlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),
.update_i(update_itlb),
.lu_access_i (itlb_lu_access),
.lu_asid_i (asid_i),
.asid_to_be_flushed_i (asid_to_be_flushed_i),
.vaddr_to_be_flushed_i(vaddr_to_be_flushed_i),
.lu_vaddr_i (lu_vaddr_i),
.lu_content_o (itlb_content),
.lu_is_page_o(itlb_is_page),
.lu_hit_o(itlb_lu_hit),
.v_st_enbl_i(1)
);
cva6_tlb #(
.CVA6Cfg (CVA6Cfg),
.TLB_ENTRIES (DATA_TLB_ENTRIES),
.ASID_WIDTH (ASID_WIDTH),
.ASID_LEN (ASID_LEN),
.VPN_LEN (VPN_LEN),
.PT_LEVELS (PT_LEVELS),
.pte_cva6_t (pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_dtlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),
.update_i(update_dtlb),
.lu_access_i (dtlb_lu_access),
.lu_asid_i (asid_i),
.asid_to_be_flushed_i (asid_to_be_flushed_i),
.vaddr_to_be_flushed_i(vaddr_to_be_flushed_i),
.lu_vaddr_i (lsu_vaddr_i),
.lu_content_o (dtlb_content),
.lu_is_page_o(dtlb_is_page),
.lu_hit_o(dtlb_lu_hit),
.v_st_enbl_i(1)
);
cva6_shared_tlb #(
.CVA6Cfg (CVA6Cfg),
.SHARED_TLB_DEPTH (64),
.SHARED_TLB_WAYS (2),
.ASID_WIDTH (ASID_WIDTH[0]),
.ASID_LEN (ASID_LEN),
.VPN_LEN (VPN_LEN),
.PT_LEVELS (PT_LEVELS),
.pte_cva6_t (pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_shared_tlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),
.enable_translation_i (enable_translation_i),
.en_ld_st_translation_i(en_ld_st_translation_i),
.asid_i (asid_i[0]),
// from TLBs
// did we miss?
.itlb_access_i(itlb_lu_access),
.itlb_hit_i (itlb_lu_hit),
.itlb_vaddr_i (icache_areq_i.fetch_vaddr),
.dtlb_access_i(dtlb_lu_access),
.dtlb_hit_i (dtlb_lu_hit),
.dtlb_vaddr_i (lsu_vaddr_i[0]),
// to TLBs, update logic
.itlb_update_o(update_itlb),
.dtlb_update_o(update_dtlb),
// Performance counters
.itlb_miss_o(itlb_miss_o),
.dtlb_miss_o(dtlb_miss_o),
.shared_tlb_access_o(shared_tlb_access),
.shared_tlb_hit_o (shared_tlb_hit),
.shared_tlb_vaddr_o (shared_tlb_vaddr),
.itlb_req_o (itlb_req),
// to update shared tlb
.shared_tlb_update_i(update_shared_tlb)
);
cva6_ptw #(
.CVA6Cfg (CVA6Cfg),
.ASID_WIDTH(ASID_WIDTH[0]),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_ptw (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_i),
.ptw_active_o (ptw_active),
.walking_instr_o (walking_instr),
.ptw_error_o (ptw_error),
.ptw_access_exception_o(ptw_access_exception),
.lsu_is_store_i(lsu_is_store_i),
// PTW memory interface
.req_port_i (req_port_i),
.req_port_o (req_port_o),
// to Shared TLB, update logic
.shared_tlb_update_o(update_shared_tlb),
.update_vaddr_o(update_vaddr),
.asid_i(asid_i[0]),
// from shared TLB
// did we miss?
.shared_tlb_access_i(shared_tlb_access),
.shared_tlb_hit_i (shared_tlb_hit),
.shared_tlb_vaddr_i (shared_tlb_vaddr),
.itlb_req_i(itlb_req),
// from CSR file
.satp_ppn_i(satp_ppn_i), // ppn from satp
.mxr_i (mxr_i),
// Performance counters
.shared_tlb_miss_o(), //open for now
// PMP
.pmpcfg_i (pmpcfg_i),
.pmpaddr_i (pmpaddr_i),
.bad_paddr_o(ptw_bad_paddr)
);
// ila_1 i_ila_1 (
// .clk(clk_i), // input wire clk
// .probe0({req_port_o.address_tag, req_port_o.address_index}),
// .probe1(req_port_o.data_req), // input wire [63:0] probe1
// .probe2(req_port_i.data_gnt), // input wire [0:0] probe2
// .probe3(req_port_i.data_rdata), // input wire [0:0] probe3
// .probe4(req_port_i.data_rvalid), // input wire [0:0] probe4
// .probe5(ptw_error), // input wire [1:0] probe5
// .probe6(update_vaddr), // input wire [0:0] probe6
// .probe7(update_ptw_itlb.valid), // input wire [0:0] probe7
// .probe8(update_ptw_dtlb.valid), // input wire [0:0] probe8
// .probe9(dtlb_lu_access), // input wire [0:0] probe9
// .probe10(lsu_vaddr_i), // input wire [0:0] probe10
// .probe11(dtlb_lu_hit), // input wire [0:0] probe11
// .probe12(itlb_lu_access), // input wire [0:0] probe12
// .probe13(icache_areq_i.fetch_vaddr), // input wire [0:0] probe13
// .probe14(itlb_lu_hit) // input wire [0:0] probe13
// );
//-----------------------
// Instruction Interface
//-----------------------
logic match_any_execute_region;
logic pmp_instr_allow;
localparam PPNWMin = (riscv::PPNW - 1 > 29) ? 29 : riscv::PPNW - 1;
assign icache_areq_o.fetch_paddr[11:0] = icache_areq_i.fetch_vaddr[11:0];
assign icache_areq_o.fetch_paddr[riscv::PLEN-1:PPNWMin+1] = //
(enable_translation_i) ? //
itlb_content[0].ppn[riscv::PPNW-1:(riscv::PPNW-(riscv::PLEN-PPNWMin-1))] : //
(riscv::PLEN-PPNWMin-1)'(icache_areq_i.fetch_vaddr[((riscv::PLEN > riscv::VLEN) ? riscv::VLEN : riscv::PLEN )-1:PPNWMin+1]);
genvar a;
generate

Comment on lines 61 to 62
logic [HYP_EXT*2:0] v_st_enbl; // v_i,g-stage enabled, s-stage enabled
logic valid;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
logic [HYP_EXT*2:0] v_st_enbl; // v_i,g-stage enabled, s-stage enabled
logic valid;
logic [HYP_EXT*2:0] v_st_enbl; // v_i,g-stage enabled, s-stage enabled
logic valid;

} [TLB_ENTRIES-1:0]
tags_q, tags_n;

pte_cva6_t [TLB_ENTRIES-1:0][HYP_EXT:0] content_q , content_n;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
pte_cva6_t [TLB_ENTRIES-1:0][HYP_EXT:0] content_q , content_n;
pte_cva6_t [TLB_ENTRIES-1:0][HYP_EXT:0] content_q, content_n;

Comment on lines 80 to 90
//at level 0 make page match always 1
//build level match vector according to vpn_match and page_match
//a level has a match if all vpn of higher levels and current have a match,
//AND the page_match is also set
//At level 0 the page match is always set, so this level will have a match
//if all vpn levels match
genvar i,x,z;
generate
for (i=0; i < TLB_ENTRIES; i++) begin

assign match_stage[i] = tags_q[i].v_st_enbl == v_st_enbl_i;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
//at level 0 make page match always 1
//build level match vector according to vpn_match and page_match
//a level has a match if all vpn of higher levels and current have a match,
//AND the page_match is also set
//At level 0 the page match is always set, so this level will have a match
//if all vpn levels match
genvar i,x,z;
generate
for (i=0; i < TLB_ENTRIES; i++) begin
assign match_stage[i] = tags_q[i].v_st_enbl == v_st_enbl_i;
//at level 0 make page match always 1
//build level match vector according to vpn_match and page_match
//a level has a match if all vpn of higher levels and current have a match,
//AND the page_match is also set
//At level 0 the page match is always set, so this level will have a match
//if all vpn levels match
genvar i, x, z;
generate
for (i = 0; i < TLB_ENTRIES; i++) begin

Comment on lines 288 to 289
//pragma translate_off
`ifndef VERILATOR
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
//pragma translate_off
`ifndef VERILATOR
// Just for checking
function int countSetBits(logic [TLB_ENTRIES-1:0] vector);
automatic int count = 0;
foreach (vector[idx]) begin
count += vector[idx];
end
return count;
endfunction

Comment on lines 291 to 292
initial begin : p_assertions
assert ((TLB_ENTRIES % 2 == 0) && (TLB_ENTRIES > 1))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
initial begin : p_assertions
assert ((TLB_ENTRIES % 2 == 0) && (TLB_ENTRIES > 1))
assert property (@(posedge clk_i) (countSetBits(lu_hit) <= 1))

initial begin : p_assertions
assert ((TLB_ENTRIES % 2 == 0) && (TLB_ENTRIES > 1))
else begin
$error("TLB size must be a multiple of 2 and greater than 1");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
$error("TLB size must be a multiple of 2 and greater than 1");
$error("More then one hit in TLB!");

$error("TLB size must be a multiple of 2 and greater than 1");
$stop();
end
assert (ASID_WIDTH[0] >= 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
assert (ASID_WIDTH[0] >= 1)
assert property (@(posedge clk_i) (countSetBits(replace_en) <= 1))

end
assert (ASID_WIDTH[0] >= 1)
else begin
$error("ASID width must be at least 1");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
$error("ASID width must be at least 1");
$error("More then one TLB entry selected for next replace!");

Copy link
Contributor

@github-actions github-actions bot left a comment

Comment on lines 174 to 182
localparam HYP_EXT = 0; //CVA6Cfg.CVA6ConfigHExtEn
localparam ASID_LEN = (riscv::XLEN == 64) ? 16 : 9;
localparam VPN_LEN = (riscv::XLEN == 64) ? (HYP_EXT ? 29 : 27) : 20;
localparam PT_LEVELS = (riscv::XLEN == 64) ? 3 : 2;
localparam int unsigned mmu_ASID_WIDTH [HYP_EXT:0] = {ASID_WIDTH};

logic [mmu_ASID_WIDTH[0]-1:0] mmu_asid_i [HYP_EXT:0];
logic [mmu_ASID_WIDTH[0]-1:0] mmu_asid_to_be_flushed_i [HYP_EXT:0];
logic [riscv::VLEN-1:0] mmu_vaddr_to_be_flushed_i [HYP_EXT:0];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
localparam HYP_EXT = 0; //CVA6Cfg.CVA6ConfigHExtEn
localparam ASID_LEN = (riscv::XLEN == 64) ? 16 : 9;
localparam VPN_LEN = (riscv::XLEN == 64) ? (HYP_EXT ? 29 : 27) : 20;
localparam PT_LEVELS = (riscv::XLEN == 64) ? 3 : 2;
localparam int unsigned mmu_ASID_WIDTH [HYP_EXT:0] = {ASID_WIDTH};
logic [mmu_ASID_WIDTH[0]-1:0] mmu_asid_i [HYP_EXT:0];
logic [mmu_ASID_WIDTH[0]-1:0] mmu_asid_to_be_flushed_i [HYP_EXT:0];
logic [riscv::VLEN-1:0] mmu_vaddr_to_be_flushed_i [HYP_EXT:0];
localparam HYP_EXT = 0; //CVA6Cfg.CVA6ConfigHExtEn
localparam ASID_LEN = (riscv::XLEN == 64) ? 16 : 9;
localparam VPN_LEN = (riscv::XLEN == 64) ? (HYP_EXT ? 29 : 27) : 20;
localparam PT_LEVELS = (riscv::XLEN == 64) ? 3 : 2;
localparam int unsigned mmu_ASID_WIDTH[HYP_EXT:0] = {ASID_WIDTH};
logic [mmu_ASID_WIDTH[0]-1:0] mmu_asid_i[HYP_EXT:0];
logic [mmu_ASID_WIDTH[0]-1:0] mmu_asid_to_be_flushed_i[HYP_EXT:0];
logic [riscv::VLEN-1:0] mmu_vaddr_to_be_flushed_i[HYP_EXT:0];

Comment on lines 186 to 188
assign mmu_asid_to_be_flushed_i[0] =asid_to_be_flushed_i;
assign mmu_vaddr_to_be_flushed_i[0] =vaddr_to_be_flushed_i;
assign mmu_lsu_vaddr_i[0]= mmu_vaddr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
assign mmu_asid_to_be_flushed_i[0] =asid_to_be_flushed_i;
assign mmu_vaddr_to_be_flushed_i[0] =vaddr_to_be_flushed_i;
assign mmu_lsu_vaddr_i[0]= mmu_vaddr;
assign mmu_asid_to_be_flushed_i[0] = asid_to_be_flushed_i;
assign mmu_vaddr_to_be_flushed_i[0] = vaddr_to_be_flushed_i;
assign mmu_lsu_vaddr_i[0] = mmu_vaddr;

Comment on lines 23 to 30
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter int unsigned INSTR_TLB_ENTRIES = 4,
parameter int unsigned DATA_TLB_ENTRIES = 4,
parameter int unsigned ASID_WIDTH [HYP_EXT:0]= {1},
parameter int unsigned ASID_LEN = 1,
parameter int unsigned VPN_LEN = 1,
parameter int unsigned PT_LEVELS = 1,
parameter logic HYP_EXT = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter int unsigned INSTR_TLB_ENTRIES = 4,
parameter int unsigned DATA_TLB_ENTRIES = 4,
parameter int unsigned ASID_WIDTH [HYP_EXT:0]= {1},
parameter int unsigned ASID_LEN = 1,
parameter int unsigned VPN_LEN = 1,
parameter int unsigned PT_LEVELS = 1,
parameter logic HYP_EXT = 0
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter int unsigned INSTR_TLB_ENTRIES = 4,
parameter int unsigned DATA_TLB_ENTRIES = 4,
parameter int unsigned ASID_WIDTH [HYP_EXT:0] = {1},
parameter int unsigned ASID_LEN = 1,
parameter int unsigned VPN_LEN = 1,
parameter int unsigned PT_LEVELS = 1,
parameter logic HYP_EXT = 0

Comment on lines 32 to 225
logic shared_tlb_hit;

logic itlb_req;

// Assignments
assign itlb_lu_access = icache_areq_i.fetch_req;
assign dtlb_lu_access = lsu_req_i;

logic [riscv::VLEN-1:0] lu_vaddr_i [HYP_EXT:0];
assign lu_vaddr_i[0]=icache_areq_i.fetch_vaddr;

cva6_tlb #(
.CVA6Cfg (CVA6Cfg),
.TLB_ENTRIES(INSTR_TLB_ENTRIES),
.ASID_WIDTH (ASID_WIDTH),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_itlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),

.update_i(update_itlb),

.lu_access_i (itlb_lu_access),
.lu_asid_i (asid_i),
.asid_to_be_flushed_i (asid_to_be_flushed_i),
.vaddr_to_be_flushed_i(vaddr_to_be_flushed_i),
.lu_vaddr_i (lu_vaddr_i),
.lu_content_o (itlb_content),

.lu_is_page_o(itlb_is_page),
.lu_hit_o (itlb_lu_hit),
.v_st_enbl_i(1)
);

cva6_tlb #(
.CVA6Cfg (CVA6Cfg),
.TLB_ENTRIES(DATA_TLB_ENTRIES),
.ASID_WIDTH (ASID_WIDTH),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_dtlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),

.update_i(update_dtlb),

.lu_access_i (dtlb_lu_access),
.lu_asid_i (asid_i),
.asid_to_be_flushed_i (asid_to_be_flushed_i),
.vaddr_to_be_flushed_i(vaddr_to_be_flushed_i),
.lu_vaddr_i (lsu_vaddr_i),
.lu_content_o (dtlb_content),

.lu_is_page_o(dtlb_is_page),
.lu_hit_o (dtlb_lu_hit),
.v_st_enbl_i(1)
);

cva6_shared_tlb #(
.CVA6Cfg (CVA6Cfg),
.SHARED_TLB_DEPTH(64),
.SHARED_TLB_WAYS (2),
.ASID_WIDTH (ASID_WIDTH[0]),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_shared_tlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),

.enable_translation_i (enable_translation_i),
.en_ld_st_translation_i(en_ld_st_translation_i),

.asid_i (asid_i[0]),
// from TLBs
// did we miss?
.itlb_access_i(itlb_lu_access),
.itlb_hit_i (itlb_lu_hit),
.itlb_vaddr_i (icache_areq_i.fetch_vaddr),

.dtlb_access_i(dtlb_lu_access),
.dtlb_hit_i (dtlb_lu_hit),
.dtlb_vaddr_i (lsu_vaddr_i[0]),

// to TLBs, update logic
.itlb_update_o(update_itlb),
.dtlb_update_o(update_dtlb),

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
input logic clk_i,
input logic rst_ni,
input logic flush_i,
input logic enable_translation_i,
input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores
// IF interface
input icache_arsp_t icache_areq_i,
output icache_areq_t icache_areq_o,
// LSU interface
// this is a more minimalistic interface because the actual addressing logic is handled
// in the LSU as we distinguish load and stores, what we do here is simple address translation
input exception_t misaligned_ex_i,
input logic lsu_req_i, // request address translation
input logic [riscv::VLEN-1:0] lsu_vaddr_i[HYP_EXT:0], // virtual address in
input logic lsu_is_store_i, // the translation is requested by a store
// if we need to walk the page table we can't grant in the same cycle
// Cycle 0
output logic lsu_dtlb_hit_o, // sent in the same cycle as the request if translation hits in the DTLB
output logic [riscv::PPNW-1:0] lsu_dtlb_ppn_o, // ppn (send same cycle as hit)
// Cycle 1
output logic lsu_valid_o, // translation is valid
output logic [riscv::PLEN-1:0] lsu_paddr_o, // translated address
output exception_t lsu_exception_o, // address translation threw an exception
// General control signals
input riscv::priv_lvl_t priv_lvl_i,
input riscv::priv_lvl_t ld_st_priv_lvl_i,
input logic sum_i,
input logic mxr_i,
// input logic flag_mprv_i,
input logic [riscv::PPNW-1:0] satp_ppn_i,
input logic [ASID_WIDTH[0]-1:0] asid_i [HYP_EXT:0],
input logic [ASID_WIDTH[0]-1:0] asid_to_be_flushed_i [HYP_EXT:0],
input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i [HYP_EXT:0],
input logic flush_tlb_i,
// Performance counters
output logic itlb_miss_o,
output logic dtlb_miss_o,
// PTW memory interface
input dcache_req_o_t req_port_i,
output dcache_req_i_t req_port_o,
// PMP
input riscv::pmpcfg_t [15:0] pmpcfg_i,
input logic [15:0][riscv::PLEN-3:0] pmpaddr_i
);
// memory management, pte for cva6
localparam type pte_cva6_t = struct packed {
// typedef struct packed {
logic [riscv::PPNW-1:0] ppn; // PPN length for
logic [1:0] rsw;
logic d;
logic a;
logic g;
logic u;
logic x;
logic w;
logic r;
logic v;
} ;
localparam type tlb_update_cva6_t = struct packed {
// typedef struct packed {
logic valid; // valid flag
logic [HYP_EXT:0][PT_LEVELS-2:0] is_page; //
logic [VPN_LEN-1:0] vpn; //
logic [HYP_EXT:0][ASID_LEN-1:0] asid; //
pte_cva6_t [HYP_EXT:0] content;
} ;
logic iaccess_err; // insufficient privilege to access this instruction page
logic daccess_err; // insufficient privilege to access this data page
logic ptw_active; // PTW is currently walking a page table
logic walking_instr; // PTW is walking because of an ITLB miss
logic ptw_error; // PTW threw an exception
logic ptw_access_exception; // PTW threw an access exception (PMPs)
logic [riscv::PLEN-1:0] ptw_bad_paddr; // PTW PMP exception bad physical addr
logic [riscv::VLEN-1:0] update_vaddr;
// tlb_update_t update_ptw_itlb, update_ptw_dtlb;
tlb_update_cva6_t update_itlb, update_dtlb, update_shared_tlb;
logic itlb_lu_access;
pte_cva6_t [HYP_EXT:0] itlb_content ;
logic [PT_LEVELS-2:0] itlb_is_page;
logic itlb_lu_hit;
logic dtlb_lu_access;
pte_cva6_t [HYP_EXT:0] dtlb_content;
logic [PT_LEVELS-2:0] dtlb_is_page;
logic dtlb_lu_hit;
logic shared_tlb_access;
logic [riscv::VLEN-1:0] shared_tlb_vaddr;
logic shared_tlb_hit;
logic itlb_req;
// Assignments
assign itlb_lu_access = icache_areq_i.fetch_req;
assign dtlb_lu_access = lsu_req_i;
logic [riscv::VLEN-1:0] lu_vaddr_i [HYP_EXT:0];
assign lu_vaddr_i[0]=icache_areq_i.fetch_vaddr;
cva6_tlb #(
.CVA6Cfg (CVA6Cfg),
.TLB_ENTRIES(INSTR_TLB_ENTRIES),
.ASID_WIDTH (ASID_WIDTH),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_itlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),
.update_i(update_itlb),
.lu_access_i (itlb_lu_access),
.lu_asid_i (asid_i),
.asid_to_be_flushed_i (asid_to_be_flushed_i),
.vaddr_to_be_flushed_i(vaddr_to_be_flushed_i),
.lu_vaddr_i (lu_vaddr_i),
.lu_content_o (itlb_content),
.lu_is_page_o(itlb_is_page),
.lu_hit_o (itlb_lu_hit),
.v_st_enbl_i(1)
);
cva6_tlb #(
.CVA6Cfg (CVA6Cfg),
.TLB_ENTRIES(DATA_TLB_ENTRIES),
.ASID_WIDTH (ASID_WIDTH),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_dtlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),
.update_i(update_dtlb),
.lu_access_i (dtlb_lu_access),
.lu_asid_i (asid_i),
.asid_to_be_flushed_i (asid_to_be_flushed_i),
.vaddr_to_be_flushed_i(vaddr_to_be_flushed_i),
.lu_vaddr_i (lsu_vaddr_i),
.lu_content_o (dtlb_content),
.lu_is_page_o(dtlb_is_page),
.lu_hit_o (dtlb_lu_hit),
.v_st_enbl_i(1)
);
cva6_shared_tlb #(
.CVA6Cfg (CVA6Cfg),
.SHARED_TLB_DEPTH(64),
.SHARED_TLB_WAYS (2),
.ASID_WIDTH (ASID_WIDTH[0]),
.ASID_LEN (ASID_LEN),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_shared_tlb (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_tlb_i),
.enable_translation_i (enable_translation_i),
.en_ld_st_translation_i(en_ld_st_translation_i),
.asid_i (asid_i[0]),
// from TLBs
// did we miss?
.itlb_access_i(itlb_lu_access),
.itlb_hit_i (itlb_lu_hit),
.itlb_vaddr_i (icache_areq_i.fetch_vaddr),
.dtlb_access_i(dtlb_lu_access),
.dtlb_hit_i (dtlb_lu_hit),
.dtlb_vaddr_i (lsu_vaddr_i[0]),
// to TLBs, update logic
.itlb_update_o(update_itlb),
.dtlb_update_o(update_dtlb),
input logic clk_i,
input logic rst_ni,
input logic flush_i,
input logic enable_translation_i,
input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores
// IF interface
input icache_arsp_t icache_areq_i,
output icache_areq_t icache_areq_o,
// LSU interface
// this is a more minimalistic interface because the actual addressing logic is handled
// in the LSU as we distinguish load and stores, what we do here is simple address translation
input exception_t misaligned_ex_i,
input logic lsu_req_i, // request address translation
input logic [riscv::VLEN-1:0] lsu_vaddr_i[HYP_EXT:0], // virtual address in
input logic lsu_is_store_i, // the translation is requested by a store
// if we need to walk the page table we can't grant in the same cycle
// Cycle 0
output logic lsu_dtlb_hit_o, // sent in the same cycle as the request if translation hits in the DTLB
output logic [riscv::PPNW-1:0] lsu_dtlb_ppn_o, // ppn (send same cycle as hit)
// Cycle 1
output logic lsu_valid_o, // translation is valid
output logic [riscv::PLEN-1:0] lsu_paddr_o, // translated address
output exception_t lsu_exception_o, // address translation threw an exception
// General control signals
input riscv::priv_lvl_t priv_lvl_i,
input riscv::priv_lvl_t ld_st_priv_lvl_i,
input logic sum_i,
input logic mxr_i,
// input logic flag_mprv_i,
input logic [riscv::PPNW-1:0] satp_ppn_i,
input logic [ASID_WIDTH[0]-1:0] asid_i[HYP_EXT:0],
input logic [ASID_WIDTH[0]-1:0] asid_to_be_flushed_i[HYP_EXT:0],
input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i[HYP_EXT:0],
input logic flush_tlb_i,

Comment on lines 227 to 256
.itlb_miss_o(itlb_miss_o),
.dtlb_miss_o(dtlb_miss_o),

.shared_tlb_access_o(shared_tlb_access),
.shared_tlb_hit_o (shared_tlb_hit),
.shared_tlb_vaddr_o (shared_tlb_vaddr),

.itlb_req_o (itlb_req),
// to update shared tlb
.shared_tlb_update_i(update_shared_tlb)
);

cva6_ptw #(
.CVA6Cfg (CVA6Cfg),
.ASID_WIDTH(ASID_WIDTH[0]),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_ptw (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_i),

.ptw_active_o (ptw_active),
.walking_instr_o (walking_instr),
.ptw_error_o (ptw_error),
.ptw_access_exception_o(ptw_access_exception),

.lsu_is_store_i(lsu_is_store_i),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
.itlb_miss_o(itlb_miss_o),
.dtlb_miss_o(dtlb_miss_o),
.shared_tlb_access_o(shared_tlb_access),
.shared_tlb_hit_o (shared_tlb_hit),
.shared_tlb_vaddr_o (shared_tlb_vaddr),
.itlb_req_o (itlb_req),
// to update shared tlb
.shared_tlb_update_i(update_shared_tlb)
);
cva6_ptw #(
.CVA6Cfg (CVA6Cfg),
.ASID_WIDTH(ASID_WIDTH[0]),
.VPN_LEN(VPN_LEN),
.PT_LEVELS(PT_LEVELS),
.pte_cva6_t(pte_cva6_t),
.tlb_update_cva6_t(tlb_update_cva6_t)
) i_ptw (
.clk_i (clk_i),
.rst_ni (rst_ni),
.flush_i(flush_i),
.ptw_active_o (ptw_active),
.walking_instr_o (walking_instr),
.ptw_error_o (ptw_error),
.ptw_access_exception_o(ptw_access_exception),
.lsu_is_store_i(lsu_is_store_i),
output logic itlb_miss_o,
output logic dtlb_miss_o,

Comment on lines +564 to +568
lsu_exception_o = {
riscv::STORE_PAGE_FAULT,
{{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, update_vaddr},
1'b1
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
lsu_exception_o = {
riscv::STORE_PAGE_FAULT,
{{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, update_vaddr},
1'b1
};
// check if the page is write-able and we are not violating privileges
// also check if the dirty flag is set
if (!dtlb_pte_q.w || daccess_err || !dtlb_pte_q.d) begin
lsu_exception_o = {
riscv::STORE_PAGE_FAULT,
{{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, lsu_vaddr_q},
1'b1
};
// Check if any PMPs are violated
end else if (!pmp_data_allow) begin
lsu_exception_o = {
riscv::ST_ACCESS_FAULT,
riscv::XLEN'(lsu_paddr_o[riscv::PLEN-1:(riscv::PLEN > riscv::VLEN) ? (riscv::PLEN - riscv::VLEN) : 0]),
1'b1
};
end
// this is a load

1'b1
};
end else begin
lsu_exception_o = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
lsu_exception_o = {
// check for sufficient access privileges - throw a page fault if necessary
if (daccess_err) begin
lsu_exception_o = {
riscv::LOAD_PAGE_FAULT,
{{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, lsu_vaddr_q},
1'b1
};
// Check if any PMPs are violated
end else if (!pmp_data_allow) begin
lsu_exception_o = {
riscv::LD_ACCESS_FAULT,
lsu_paddr_o[riscv::PLEN-1:(riscv::PLEN>riscv::VLEN)?(riscv::PLEN-riscv::VLEN) : 0],
1'b1
};
end
end
end else
// ---------
// DTLB Miss
// ---------
// watch out for exceptions
if (ptw_active && !walking_instr) begin
// page table walker threw an exception
if (ptw_error) begin
// an error makes the translation valid
lsu_valid_o = 1'b1;
// the page table walker can only throw page faults
if (lsu_is_store_q) begin
lsu_exception_o = {
riscv::STORE_PAGE_FAULT,
{{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, update_vaddr},
1'b1
};
end else begin
lsu_exception_o = {
riscv::LOAD_PAGE_FAULT,
{{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, update_vaddr},
1'b1
};
end
end
if (ptw_access_exception) begin
// an error makes the translation valid
lsu_valid_o = 1'b1;
// Any fault of the page table walk should be based of the original access type
end

Comment on lines +571 to +572
riscv::LOAD_PAGE_FAULT,
{{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, update_vaddr},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
riscv::LOAD_PAGE_FAULT,
{{riscv::XLEN - riscv::VLEN{lsu_vaddr_q[riscv::VLEN-1]}}, update_vaddr},
riscv::LD_ACCESS_FAULT,
ptw_bad_paddr[riscv::PLEN-1:(riscv::PLEN>riscv::VLEN)?(riscv::PLEN-riscv::VLEN) : 0],

Comment on lines +577 to +585

if (ptw_access_exception) begin
// an error makes the translation valid
lsu_valid_o = 1'b1;
// Any fault of the page table walk should be based of the original access type
lsu_exception_o = {riscv::LD_ACCESS_FAULT, ptw_bad_paddr[riscv::PLEN-1:(riscv::PLEN > riscv::VLEN) ? (riscv::PLEN - riscv::VLEN) : 0], 1'b1};
end
end
end // If translation is not enabled, check the paddr immediately against PMPs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
if (ptw_access_exception) begin
// an error makes the translation valid
lsu_valid_o = 1'b1;
// Any fault of the page table walk should be based of the original access type
lsu_exception_o = {riscv::LD_ACCESS_FAULT, ptw_bad_paddr[riscv::PLEN-1:(riscv::PLEN > riscv::VLEN) ? (riscv::PLEN - riscv::VLEN) : 0], 1'b1};
end
end
end // If translation is not enabled, check the paddr immediately against PMPs
end // If translation is not enabled, check the paddr immediately against PMPs

Comment on lines +587 to +590
if (lsu_is_store_q) begin
lsu_exception_o = {riscv::ST_ACCESS_FAULT, lsu_paddr_o[riscv::PLEN-1:(riscv::PLEN > riscv::VLEN) ? (riscv::PLEN - riscv::VLEN) : 0], 1'b1};
end else begin
lsu_exception_o = {riscv::LD_ACCESS_FAULT, lsu_paddr_o[riscv::PLEN-1:(riscv::PLEN > riscv::VLEN) ? (riscv::PLEN - riscv::VLEN) : 0], 1'b1};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
if (lsu_is_store_q) begin
lsu_exception_o = {riscv::ST_ACCESS_FAULT, lsu_paddr_o[riscv::PLEN-1:(riscv::PLEN > riscv::VLEN) ? (riscv::PLEN - riscv::VLEN) : 0], 1'b1};
end else begin
lsu_exception_o = {riscv::LD_ACCESS_FAULT, lsu_paddr_o[riscv::PLEN-1:(riscv::PLEN > riscv::VLEN) ? (riscv::PLEN - riscv::VLEN) : 0], 1'b1};
if (lsu_is_store_q) begin
lsu_exception_o = {
riscv::ST_ACCESS_FAULT,
lsu_paddr_o[riscv::PLEN-1:(riscv::PLEN>riscv::VLEN)?(riscv::PLEN-riscv::VLEN) : 0],
1'b1
};
end else begin
lsu_exception_o = {
riscv::LD_ACCESS_FAULT,
lsu_paddr_o[riscv::PLEN-1:(riscv::PLEN>riscv::VLEN)?(riscv::PLEN-riscv::VLEN) : 0],
1'b1
};
end

Comment on lines +143 to +144
// update the correct page table level
assign shared_tlb_update_o.is_page[x] = (ptw_lvl_q == (x));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
// update the correct page table level
assign shared_tlb_update_o.is_page[x] = (ptw_lvl_q == (x));
// update the correct page table level
assign shared_tlb_update_o.is_page[x] = (ptw_lvl_q == (x));

core/mmu_unify/cva6_tlb.sv Outdated Show resolved Hide resolved
core/mmu_unify/cva6_tlb.sv Outdated Show resolved Hide resolved
core/mmu_unify/cva6_tlb.sv Outdated Show resolved Hide resolved
core/mmu_unify/cva6_tlb.sv Outdated Show resolved Hide resolved
Comment on lines 254 to 263
// sequential process
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
tags_q <= '{default: 0};
content_q <= '{default: 0};
plru_tree_q <= '{default: 0};
end else begin
tags_q <= tags_n;
content_q <= content_n;
plru_tree_q <= plru_tree_n;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
// sequential process
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
tags_q <= '{default: 0};
content_q <= '{default: 0};
plru_tree_q <= '{default: 0};
end else begin
tags_q <= tags_n;
content_q <= content_n;
plru_tree_q <= plru_tree_n;
initial begin : p_assertions
assert ((TLB_ENTRIES % 2 == 0) && (TLB_ENTRIES > 1))
else begin
$error("TLB size must be a multiple of 2 and greater than 1");
$stop();
end
assert (ASID_WIDTH >= 1)
else begin
$error("ASID width must be at least 1");
$stop();
end

$error("TLB size must be a multiple of 2 and greater than 1");
$stop();
end
assert (ASID_WIDTH >= 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
assert (ASID_WIDTH >= 1)
assert property (@(posedge clk_i) (countSetBits(replace_en) <= 1))

end

`endif
//pragma translate_on
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
//pragma translate_on
//pragma translate_on

Copy link
Contributor

❌ failed run, report available here.

1 similar comment
Copy link
Contributor

❌ failed run, report available here.

Copy link
Contributor

✔️ successful run, report available here.

AngelaGonzalezMarino and others added 2 commits December 18, 2023 12:13
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
end
replace_en[i] = en;
end
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
end
//--------------
// Sanity checks
//--------------

Comment on lines 254 to 263
// sequential process
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
tags_q <= '{default: 0};
content_q <= '{default: 0};
plru_tree_q <= '{default: 0};
end else begin
tags_q <= tags_n;
content_q <= content_n;
plru_tree_q <= plru_tree_n;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
// sequential process
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
tags_q <= '{default: 0};
content_q <= '{default: 0};
plru_tree_q <= '{default: 0};
end else begin
tags_q <= tags_n;
content_q <= content_n;
plru_tree_q <= plru_tree_n;
//pragma translate_off
`ifndef VERILATOR
initial begin : p_assertions
assert ((TLB_ENTRIES % 2 == 0) && (TLB_ENTRIES > 1))
else begin
$error("TLB size must be a multiple of 2 and greater than 1");
$stop();
end
assert (ASID_WIDTH >= 1)
else begin
$error("ASID width must be at least 1");
$stop();
end

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
Contributor

✔️ successful run, report available here.

2 similar comments
Copy link
Contributor

✔️ successful run, report available here.

Copy link
Contributor

✔️ successful run, report available here.

@jquevremont jquevremont added the Status:Do-not-merge Pull request that should not be merged (yet) label Dec 19, 2023
@jquevremont jquevremont self-assigned this Dec 19, 2023
@jquevremont jquevremont requested review from jquevremont and removed request for zarubaf and JeanRochCoulon December 19, 2023 08:54
@jquevremont
Copy link
Contributor

@AngelaGonzalezMarino will issue another PR when linting is fixed, to make the review less verbous.

@JeanRochCoulon
Copy link
Contributor

@AEzzejjari Angela is merging the 3 MMUs. Thsi can have an impact on Code Coverage. May I ask you to run CC tests to check the non regression ?

Comment on lines 155 to 158
for (x=0; x < PT_LEVELS; x++) begin
assign page_match[i][x] = x==0 ? 1 :shared_tag_rd[i].is_page[PT_LEVELS-1-x];
assign vpn_match[i][x] = vpn_q[x] == shared_tag_rd[i].vpn[x];
assign level_match[i][x] = &vpn_match[i][PT_LEVELS-1:x] & page_match[i][x];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
for (x=0; x < PT_LEVELS; x++) begin
assign page_match[i][x] = x==0 ? 1 :shared_tag_rd[i].is_page[PT_LEVELS-1-x];
assign vpn_match[i][x] = vpn_q[x] == shared_tag_rd[i].vpn[x];
assign level_match[i][x] = &vpn_match[i][PT_LEVELS-1:x] & page_match[i][x];
for (x = 0; x < PT_LEVELS; x++) begin
assign page_match[i][x] = x == 0 ? 1 : shared_tag_rd[i].is_page[PT_LEVELS-1-x];
assign vpn_match[i][x] = vpn_q[x] == shared_tag_rd[i].vpn[x];
assign level_match[i][x] = &vpn_match[i][PT_LEVELS-1:x] & page_match[i][x];

Comment on lines 165 to 169
for (w=0; w < PT_LEVELS; w++) begin
assign vpn_d[w] = (enable_translation_i & itlb_access_i & ~itlb_hit_i & ~dtlb_access_i) ? //
itlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : //
((en_ld_st_translation_i & dtlb_access_i & ~dtlb_hit_i)? //
dtlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : vpn_q[w]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
for (w=0; w < PT_LEVELS; w++) begin
assign vpn_d[w] = (enable_translation_i & itlb_access_i & ~itlb_hit_i & ~dtlb_access_i) ? //
itlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : //
((en_ld_st_translation_i & dtlb_access_i & ~dtlb_hit_i)? //
dtlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : vpn_q[w]);
for (w = 0; w < PT_LEVELS; w++) begin
assign vpn_d[w] = (enable_translation_i & itlb_access_i & ~itlb_hit_i & ~dtlb_access_i) ? //
itlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : //
((en_ld_st_translation_i & dtlb_access_i & ~dtlb_hit_i) ? //
dtlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : vpn_q[w]);

Comment on lines +204 to +205
for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin
// we got a hit so update the pointer as it was least recently used
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin
// we got a hit so update the pointer as it was least recently used
for (
int unsigned i = 0; i < TLB_ENTRIES; i++
) begin
// we got a hit so update the pointer as it was least recently used

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this the desired style?

//--------------

//pragma translate_off
`ifndef VERILATOR
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
`ifndef VERILATOR
`ifndef VERILATOR

$stop();
end

`endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
`endif
`endif

//identify page_match for all TLB Entries

for (x = 0; x < PT_LEVELS; x++) begin
assign page_match[i][x] = x == 0 ? 1 :shared_tag_rd[i].is_page[PT_LEVELS-1-x];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
assign page_match[i][x] = x == 0 ? 1 :shared_tag_rd[i].is_page[PT_LEVELS-1-x];
assign page_match[i][x] = x == 0 ? 1 : shared_tag_rd[i].is_page[PT_LEVELS-1-x];

Comment on lines 165 to 169
for (w = 0; w < PT_LEVELS; w++) begin
assign vpn_d[w] = (enable_translation_i & itlb_access_i & ~itlb_hit_i & ~dtlb_access_i) ? //
itlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : //
((en_ld_st_translation_i & dtlb_access_i & ~dtlb_hit_i) ? //
dtlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : vpn_q[w]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
for (w = 0; w < PT_LEVELS; w++) begin
assign vpn_d[w] = (enable_translation_i & itlb_access_i & ~itlb_hit_i & ~dtlb_access_i) ? //
itlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : //
((en_ld_st_translation_i & dtlb_access_i & ~dtlb_hit_i) ? //
dtlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : vpn_q[w]);
for (w = 0; w < PT_LEVELS; w++) begin
assign vpn_d[w] = (enable_translation_i & itlb_access_i & ~itlb_hit_i & ~dtlb_access_i) ? //
itlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : //
((en_ld_st_translation_i & dtlb_access_i & ~dtlb_hit_i) ? //
dtlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : vpn_q[w]);

// Sanity checks
//--------------

//pragma translate_off
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
//pragma translate_off
//pragma translate_off

Comment on lines +167 to +169
itlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : //
((en_ld_st_translation_i & dtlb_access_i & ~dtlb_hit_i) ? //
dtlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : vpn_q[w]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change
itlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : //
((en_ld_st_translation_i & dtlb_access_i & ~dtlb_hit_i) ? //
dtlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : vpn_q[w]);
itlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : //
((en_ld_st_translation_i & dtlb_access_i & ~dtlb_hit_i) ? //
dtlb_vaddr_i[12+((VPN_LEN/PT_LEVELS)*(w+1))-1:12+((VPN_LEN/PT_LEVELS)*w)] : vpn_q[w]);

en &= ~plru_tree_q[idx_base+(i>>shift)];
end
end

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[verible-verilog-format] reported by reviewdog 🐶

Suggested change

@AngelaGonzalezMarino
Copy link
Contributor Author

After fixing linting issues I will open a new pull request to have it cleaner

@jquevremont
Copy link
Contributor

jquevremont commented Dec 19, 2023

@AEzzejjari Angela is merging the 3 MMUs. Thsi can have an impact on Code Coverage. May I ask you to run CC tests to check the non regression ?

@JeanRochCoulon, @AEzzejjari, you can give a look to #1725, which supersedes this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status:Do-not-merge Pull request that should not be merged (yet)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants